package web;

import java.io.IOException;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;

import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;
import org.springframework.beans.factory.annotation.Autowired;

import service.ContaService;
import service.ManutencaoService;
import service.TransacaoService;
import entity.ContaCredito;
import entity.Fatura;
import entity.Transacao;
import exceptions.ServiceException;


public class ManterCompraMB extends ManutencaoCRUDBean<Transacao> implements
		Serializable {

	private static final long serialVersionUID = 7863504781978243773L;

	@Autowired
	private TransacaoService transacaoService;

	@Autowired
	private ContaService cartaoService;

	private Transacao compra;

	private ContaCredito contaCredito;

	private List<ContaCredito> listaDeCartoes;

	private List<Transacao> listaCompras;

	private UploadedFile uploadedFile;

	private Map<Integer, Fatura> mapaFaturasPorValor;

	private List<Fatura> faturasPorValor;

	@Override
	protected void prepararAdicionar() {
		criarCompra();
	}

	private void criarCompra() {
		compra = transacaoService.criarTransacao();
	}

	public void importarArquivo() {
		try {
			listaCompras = transacaoService.importarArquivoDeTransacoes(
					contaCredito, uploadedFile.getInputstream());
			carregarListaFaturasPorValor();

		} catch (IOException e) {
			throw new ServiceException("Falhar ao ler os dados do arquivo.", e);
		}
	}

	public void carregarListaFaturasPorValor() {

		mapaFaturasPorValor = new HashMap<Integer, Fatura>();

		for (Transacao compra : listaCompras) {

			final Fatura faturaParcela = compra.getFaturaParcela();

			if (compra.isImportar() && faturaParcela != null) {

				final Integer anoMesReferencia = faturaParcela
						.getAnoMesReferencia();

				if (mapaFaturasPorValor.get(anoMesReferencia) == null) {
					faturaParcela.setValorTotal(BigDecimal.ZERO);
					mapaFaturasPorValor.put(anoMesReferencia, faturaParcela);
				}
			}
		}

		for (Transacao compra : listaCompras) {
			final Fatura faturaParcela = compra.getFaturaParcela();

			if (compra.isImportar() && faturaParcela != null) {

				final Fatura fatura = mapaFaturasPorValor.get(faturaParcela
						.getAnoMesReferencia());

				fatura.setValorTotal(fatura.getValorTotal().add(
						compra.getValorParcela()));

			}
		}
		faturasPorValor = new ArrayList<Fatura>(mapaFaturasPorValor.values());

		Collections.sort(faturasPorValor, new Comparator<Fatura>() {
			@Override
			public int compare(Fatura o1, Fatura o2) {
				return o1.getAnoMesReferencia().compareTo(
						o2.getAnoMesReferencia());
			}
		});
	}

	public void salvarImportacao() {
		transacaoService.salvarImportacao(listaCompras);
	}

	public void doUpload(FileUploadEvent fileUploadEvent) {
		uploadedFile = fileUploadEvent.getFile();
		String fileNameUploaded = uploadedFile.getFileName();
		long fileSizeUploaded = uploadedFile.getSize();
		String infoAboutFile = "<br/> Arquivo recebido: <b>" + fileNameUploaded
				+ "</b><br/>" + "Tamanho do Arquivo: <b>" + fileSizeUploaded
				+ "</b>";
		FacesContext facesContext = FacesContext.getCurrentInstance();
		facesContext.addMessage(null,
				new FacesMessage("Sucesso", infoAboutFile));

	}

	@Override
	public void inicializar() {
	    	super.inicializar();
		criarCompra();
		listaDeCartoes = cartaoService.listarCartoesCreditoComFaturas();

		super.doAdicionarAction();
	}

	@Override
	protected void prepararEditar() {
	}

	@Override
	public void doSalvarAction() {
		super.doSalvarAction();
	}

	@Override
	public void doDetalharAction() {
		super.doDetalharAction();
	}

	@Override
	public ManutencaoService<Transacao> getService() {
		return transacaoService;
	}

	@Override
	public Transacao getEntidade() {
		return compra;
	}

	@Override
	public void setEntidade(Transacao entidade) {
		compra = entidade;
	}

	public List<ContaCredito> getListaDeCartoes() {
		return listaDeCartoes;
	}

	public ContaCredito getContaCredito() {
		return contaCredito;
	}

	public void setContaCredito(ContaCredito cartaoCredito) {
		this.contaCredito = cartaoCredito;
	}

	public List<Transacao> getListaCompras() {
		return listaCompras;
	}

	public void setListaCompras(List<Transacao> listaCompras) {
		this.listaCompras = listaCompras;
	}

	public List<Fatura> getFaturasPorValor() {
		return faturasPorValor;
	}
}
